<!DOCTYPE html>
<html lang=zh-CN>
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="google-site-verification" content="xBT4GhYoi5qRD5tr338pgPM5OWHHIDR6mNg1a3euekI" />
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <meta property="og:description" content="samuel-24276的博客">
    <meta property="og:type" content="website">
    <meta name="description" content="samuel-24276的博客">
    <meta name="keyword"  content="aircloud">
    <link rel="shortcut icon" href="/myblog/img/favicon.ico">

    <title>
        
        函数对象与函数适配器Binder - samuel-24276的博客 | samuel-24276&#39;s Blog
        
    </title>

    <!-- Custom CSS -->
    
<link rel="stylesheet" href="/myblog/css/aircloud.css">

    
<link rel="stylesheet" href="/myblog/css/gitment.css">

    <!--<link rel="stylesheet" href="https://imsun.github.io/gitment/style/default.css">-->
    <link href="//at.alicdn.com/t/font_620856_28hi1hpxx24.css" rel="stylesheet" type="text/css">
    <!-- ga & ba script hoook -->
    <script></script>
<meta name="generator" content="Hexo 7.1.1"></head>

<body>

<div class="site-nav-toggle" id="site-nav-toggle">
    <button>
        <span class="btn-bar"></span>
        <span class="btn-bar"></span>
        <span class="btn-bar"></span>
    </button>
</div>

<div class="index-about">
    <i> Like what you do, do what you like </i>
</div>

<div class="index-container">
    
    <div class="index-left">
        
<div class="nav" id="nav">
    <div class="avatar-name">
        <div class="avatar ">
            <img src="/myblog/img/avatar.jpg" />
        </div>
        <div class="name">
            <i>samuel-24276</i>
        </div>
    </div>
    <div class="contents" id="nav-content">
        <ul>
            <li >
                <a href="/myblog/">
                    <i class="iconfont icon-shouye1"></i>
                    <span>主页</span>
                </a>
            </li>
            <li >
                <a href="/myblog/tags">
                    <i class="iconfont icon-biaoqian1"></i>
                    <span>标签</span>
                </a>
            </li>
            <li >
                <a href="/myblog/archives">
                    <i class="iconfont icon-guidang2"></i>
                    <span>存档</span>
                </a>
            </li>
            <li >
                <a href="/myblog/collect/">
                    <i class="iconfont icon-shoucang1"></i>
                    <span>收藏</span>
                </a>
            </li>
            <li >
                <a href="/myblog/about/">
                    <i class="iconfont icon-guanyu2"></i>
                    <span>关于</span>
                </a>
            </li>
            
            <li>
                <a id="search">
                    <i class="iconfont icon-sousuo1"></i>
                    <span>搜索</span>
                </a>
            </li>
            
        </ul>
    </div>
    
        <div id="toc" class="toc-article">
    <ol class="toc"><li class="toc-item toc-level-1"><a class="toc-link" href="#1-%E5%87%BD%E6%95%B0%E5%AF%B9%E8%B1%A1"><span class="toc-text">1.函数对象</span></a><ol class="toc-child"><li class="toc-item toc-level-2"><a class="toc-link" href="#1-1-%E7%9B%B8%E6%AF%94%E6%99%AE%E9%80%9A%E5%87%BD%E6%95%B0%E7%9A%84%E4%BC%98%E7%82%B9"><span class="toc-text">1.1.相比普通函数的优点</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#1-2-%E9%A2%84%E5%AE%9A%E4%B9%89%E7%9A%84Function-Object"><span class="toc-text">1.2.预定义的Function Object</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#1-3-%E4%BB%A5%E5%87%BD%E6%95%B0%E5%AF%B9%E8%B1%A1%E4%B8%BA%E6%8E%92%E5%BA%8F%E5%87%86%E5%88%99"><span class="toc-text">1.3.以函数对象为排序准则</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#1-4-%E6%94%B9%E5%8F%98function-object%E7%9A%84%E5%86%85%E9%83%A8%E7%8A%B6%E6%80%81%EF%BC%88Internal-State"><span class="toc-text">1.4.改变function object的内部状态（Internal State)</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#1-5-Predicate%EF%BC%88%E5%88%A4%E6%96%AD%E5%BC%8F%EF%BC%89%E4%B8%8Efunction-object%EF%BC%88%E5%87%BD%E6%95%B0%E5%AF%B9%E8%B1%A1%EF%BC%89"><span class="toc-text">1.5.Predicate（判断式）与function object（函数对象）</span></a></li></ol></li><li class="toc-item toc-level-1"><a class="toc-link" href="#2-%E5%87%BD%E6%95%B0%E9%80%82%E9%85%8D%E5%99%A8Binder"><span class="toc-text">2.函数适配器Binder</span></a><ol class="toc-child"><li class="toc-item toc-level-2"><a class="toc-link" href="#2-1-%E4%BD%BF%E7%94%A8STL%E9%A2%84%E5%AE%9A%E4%B9%89%E5%87%BD%E6%95%B0%E5%AF%B9%E8%B1%A1%E6%97%B6%E5%85%B7%E4%BD%93%E6%8C%87%E5%AE%9A%E5%8F%82%E6%95%B0"><span class="toc-text">2.1.使用STL预定义函数对象时具体指定参数</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#2-2-%E8%B0%83%E7%94%A8%E5%85%A8%E5%B1%80%E5%87%BD%E6%95%B0"><span class="toc-text">2.2.调用全局函数</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#2-3-%E8%B0%83%E7%94%A8%E6%88%90%E5%91%98%E5%87%BD%E6%95%B0"><span class="toc-text">2.3.调用成员函数</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#2-4-%E7%BB%91%E5%AE%9A%E8%87%B3%E6%95%B0%E6%8D%AE%E6%88%90%E5%91%98"><span class="toc-text">2.4.绑定至数据成员</span></a></li></ol></li></ol>
</div>
    
</div>


<div class="search-field" id="search-field">
    <div class="search-bg" id="search-bg"></div>
    <div class="search-container">
        <div class="search-input">
            <span id="esc-search"> <i class="icon-fanhui iconfont"></i></span>
            <input id="search-input"/>
            <span id="begin-search">搜索</span>
        </div>
        <div class="search-result-container" id="search-result-container">

        </div>
    </div>
</div>

        <div class="index-about-mobile">
            <i> Like what you do, do what you like </i>
        </div>
    </div>
    
    <div class="index-middle">
        <!-- Main Content -->
        


<div class="post-container">
    <div class="post-title">
        函数对象与函数适配器Binder
    </div>

    <div class="post-meta">
        <span class="attr">发布于：<span>2021-04-28 15:14:38</span></span>
        
        <span class="attr">标签：/
        
        <a class="tag" href="/myblog/tags/#C++" title="C++">C++</a>
        <span>/</span>
        
        
        </span>
        <span class="attr">访问：<span id="busuanzi_value_page_pv"></span>
</span>
</span>
    </div>
    <div class="post-content no-indent">
        <h1 id="1-函数对象"><a href="#1-函数对象" class="headerlink" title="1.函数对象"></a>1.函数对象</h1><p><em>function object</em>(函数对象），简称<em>functors</em>(仿函），是传递给算法的“函数型实参”，具备<strong>函数行为</strong>：可以使用小括号（）传递实参，借以调用某个东西。做法是定义类时定义成员函数operator()，给予适当的参数类型和返回类型。</p>
<h2 id="1-1-相比普通函数的优点"><a href="#1-1-相比普通函数的优点" class="headerlink" title="1.1.相比普通函数的优点"></a>1.1.相比普通函数的优点</h2><ul>
<li><p>1.<strong>函数对象是一种带状态（state）的函数</strong>。它可以拥有成员函数和成员变量，在同一时间点，相同类型的两个不同的函数对象所表述的相同机能（same functionality），可具备不同的状态。</p>
</li>
<li><p>2.<strong>每个函数对象有自己的类型</strong>。寻常函数，只有在其<strong>签名式</strong>（函数类型，参数类型，参数个数）不同时，才算类型不同。而函数对象即使签名式相同，也可由不同的类型。事实上由函数对象定义的每一个函数行为都有其自己的类型。因此我们可以把函数行为当作template参数使用。<strong>这使得不同类型的容器可以使用同类型的函数对象作为排序准则</strong>。也可确保你不会在“排序准则不同”的集合间赋值、合并或比较。</p>
</li>
<li><p>3.<strong>函数对象通常比寻常函数速度快</strong>。就template概念而言，由于更多细节在编译期就已经确定，所以通常可能进行更好的优化。</p>
</li>
</ul>
<h2 id="1-2-预定义的Function-Object"><a href="#1-2-预定义的Function-Object" class="headerlink" title="1.2.预定义的Function Object"></a>1.2.预定义的Function Object</h2><p>添加头文件： <code>#include&lt;functional&gt;</code></p>
<table>
<thead>
<tr>
<th>表达式</th>
<th>效果</th>
</tr>
</thead>
<tbody><tr>
<td>negate<type>()</td>
<td>-param取负</td>
</tr>
<tr>
<td>plus<type>()</td>
<td>param1 + param2</td>
</tr>
<tr>
<td>minus<type>()</td>
<td>param1 - param2</td>
</tr>
<tr>
<td>multiplies<type>()</td>
<td>param1 * param2</td>
</tr>
<tr>
<td>divides<type>()</td>
<td>param1 &#x2F; param2</td>
</tr>
<tr>
<td>modulus<type>()</td>
<td>param1 % param2</td>
</tr>
<tr>
<td>equal_to<type>()</td>
<td>param1 &#x3D;&#x3D; param2</td>
</tr>
<tr>
<td>not_equal_to<type>()</td>
<td>param1 ！&#x3D; param2</td>
</tr>
<tr>
<td>less<type>()</td>
<td>param1 &lt; param2</td>
</tr>
<tr>
<td>greater<type>()</td>
<td>param1 &gt; param2</td>
</tr>
<tr>
<td>less_equal<type>()</td>
<td>param1 &lt;&#x3D; param2</td>
</tr>
<tr>
<td>greater_equal<type>()</td>
<td>param1 &gt;&#x3D; param2</td>
</tr>
<tr>
<td>logical_not<type>()</td>
<td>！param</td>
</tr>
<tr>
<td>logical_and<type>()</td>
<td>param1 &amp;&amp; param2</td>
</tr>
<tr>
<td>logical_or<type>()</td>
<td>param1 &#124;&#124; param2</td>
</tr>
<tr>
<td>bit_and<type>()</td>
<td>param1 &amp; param2</td>
</tr>
<tr>
<td>bit_or<type>()</td>
<td>param1 &#124; param2</td>
</tr>
<tr>
<td>bit_xor<type>()</td>
<td>param1 ^ param2</td>
</tr>
</tbody></table>
<p>对对象进行排序或比较（用于排序函数和associative容器）时，默认以less&lt;&gt;为比较准则，一次默认的排序操作是升序。Unordered容器的默认相等性准则是equal_to&lt;&gt;。</p>
<h2 id="1-3-以函数对象为排序准则"><a href="#1-3-以函数对象为排序准则" class="headerlink" title="1.3.以函数对象为排序准则"></a>1.3.以函数对象为排序准则</h2><figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">class</span> <span class="title class_">Person</span></span><br><span class="line">&#123;</span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line">    <span class="function">string <span class="title">firstname</span><span class="params">()</span> <span class="type">const</span></span>;</span><br><span class="line">    <span class="function">string <span class="title">lastname</span><span class="params">()</span> <span class="type">const</span></span>;</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">PersonSortCriterion</span></span><br><span class="line">&#123;</span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line">    <span class="function"><span class="type">bool</span> <span class="title">operator</span><span class="params">()</span> <span class="params">(<span class="type">const</span> Person&amp; p1, <span class="type">const</span> Person&amp; p2)</span> <span class="type">const</span></span></span><br><span class="line"><span class="function">    </span>&#123;</span><br><span class="line">        <span class="keyword">return</span> p1.<span class="built_in">lastname</span>() &lt; p2.<span class="built_in">lastname</span>() ||</span><br><span class="line">               (p1.<span class="built_in">lastname</span>() == p2.<span class="built_in">lastname</span>() &amp;&amp; p1.<span class="built_in">firstname</span>() &lt; p2.<span class="built_in">firstname</span>());</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="type">int</span> <span class="title">main</span><span class="params">()</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">    set&lt;Person, PersonSortCriterion&gt; coll;</span><br><span class="line">	<span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>排序准则PersonSortCriterion是个class，所以你可以把它当作set的template实参。若以寻常函数担任排序准则，则使用双参判断式如下：</p>
<figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">class</span> <span class="title class_">Person</span></span><br><span class="line">&#123;</span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line">    <span class="function">string <span class="title">firstname</span><span class="params">()</span> <span class="type">const</span></span>;</span><br><span class="line">    <span class="function">string <span class="title">lastname</span><span class="params">()</span> <span class="type">const</span></span>;</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="type">bool</span> <span class="title">PersonSortCriterion</span><span class="params">(<span class="type">const</span> Person &amp;p1, <span class="type">const</span> Person &amp;p2)</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">return</span> p1.<span class="built_in">lastname</span>() &lt; p2.<span class="built_in">lastname</span>() ||</span><br><span class="line">           (p1.<span class="built_in">lastname</span>() == p2.<span class="built_in">lastname</span>() &amp;&amp; p1.<span class="built_in">firstname</span>() &lt; p2.<span class="built_in">firstname</span>());</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="type">int</span> <span class="title">main</span><span class="params">()</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">    deque&lt;Person&gt; coll;</span><br><span class="line">	<span class="built_in">sort</span>(coll.<span class="built_in">begin</span>(), coll.<span class="built_in">end</span>(), PersonSortCriterion);</span><br><span class="line">	<span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>观察可知，使用双参判断式作为排序准则，则只能使用全局的sort（）函数而不能直接将排序准则作为容器初始化的参数，因此不够方便也不够快。我们还可以设计出“表现不同排序准则却有着相同类型”的函数对象，代码如下：</p>
<figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">class</span> <span class="title class_">RuntimeStringCmp</span></span><br><span class="line">&#123;</span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line">    <span class="keyword">enum</span> <span class="title class_">cmp_mode</span>   <span class="comment">//两种不同的比较准则都是同一类型RuntimeStringCmp </span></span><br><span class="line">    &#123;</span><br><span class="line">        normal,</span><br><span class="line">        nocase</span><br><span class="line">    &#125;;</span><br><span class="line">    <span class="built_in">RuntimeStringCmp</span>(cmp_mode m=normal):<span class="built_in">mode</span>(m)&#123;&#125;</span><br><span class="line">    <span class="function"><span class="type">bool</span> <span class="title">operator</span><span class="params">()</span><span class="params">(<span class="type">const</span> string&amp; s1, <span class="type">const</span> string&amp; s2)</span> <span class="type">const</span></span></span><br><span class="line"><span class="function">    </span>&#123;</span><br><span class="line">        <span class="keyword">if</span>(mode==normal)</span><br><span class="line">            <span class="keyword">return</span> s1 &lt; s2;</span><br><span class="line">        <span class="keyword">else</span></span><br><span class="line">        &#123;</span><br><span class="line">            <span class="keyword">return</span> <span class="built_in">lexicographical_compare</span>(s1.<span class="built_in">begin</span>(), s1.<span class="built_in">end</span>(), s2.<span class="built_in">begin</span>(), s2.<span class="built_in">end</span>(), nocase_compare);<span class="comment">//lexicographical_compare为模板函数</span></span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line"><span class="keyword">private</span>:</span><br><span class="line">    <span class="type">const</span> cmp_mode mode;</span><br><span class="line">    <span class="function"><span class="type">static</span> <span class="type">bool</span> <span class="title">nocase_compare</span><span class="params">(<span class="type">char</span> c1, <span class="type">char</span> c2)</span></span></span><br><span class="line"><span class="function">    </span>&#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="built_in">toupper</span>(c1) &lt; <span class="built_in">toupper</span>(c2);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="type">void</span> <span class="title">fillAndPrint</span><span class="params">(map&lt;string,string&gt;&amp; coll)</span></span>;<span class="comment">//填充字符串信息</span></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="type">int</span> <span class="title">main</span><span class="params">()</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">    map&lt;string, string&gt; coll1;</span><br><span class="line">    <span class="built_in">fillAndPrint</span>(coll1);</span><br><span class="line">    <span class="function">RuntimeStringCmp <span class="title">ignorecase</span><span class="params">(RuntimeStringCmp::nocase)</span></span>;<span class="comment">//忽略大小写进行排序</span></span><br><span class="line"></span><br><span class="line">    <span class="function">map&lt;string, string&gt; <span class="title">coll2</span><span class="params">(ignorecase)</span></span>;</span><br><span class="line">    <span class="built_in">fillAndPrint</span>(coll2);</span><br><span class="line">	<span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>可以看出coll1和coll2都是同一类型RuntimeStringCmp，但却采用了不同的排序准则，这是由函数对象的内部状态决定的。函数对象传递有两种方式：by value和by reference,使用by value可以传递常量表达式或暂存表达式，但却无法取得并处理函数对象的内部状态，因为算法改变的是函数对象的拷贝。</p>
<h2 id="1-4-改变function-object的内部状态（Internal-State"><a href="#1-4-改变function-object的内部状态（Internal-State" class="headerlink" title="1.4.改变function object的内部状态（Internal State)"></a>1.4.改变function object的内部状态（Internal State)</h2><p>有三个方法可以从“运用了function object”的算法中获取“结果”或“反馈”：<br>1.在外部持有状态，并让function object指向它。<br>2.以By reference方式传递funtion object。<br>3.利用for_each()算法的返回值。</p>
<p>其中以By reference方式传递funtion object，只需将template实参明白标识，就可以达到这个效果。示例代码如下：</p>
<figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">generate_n&lt;back_insert_iterator&lt;list&lt;<span class="type">int</span>&gt;&gt;, <span class="type">int</span>, IntSequence&amp;&gt;</span><br><span class="line">    (<span class="built_in">back_inserter</span>(coll),   <span class="comment">//start</span></span><br><span class="line">    <span class="number">4</span>,                      <span class="comment">//元素数量</span></span><br><span class="line">    <span class="built_in">seq</span>(<span class="number">1</span>));                <span class="comment">//seq是一个实现对参数自增1的函数对象</span></span><br></pre></td></tr></table></figure>

<p>for_each()算法有一个独门绝技，可以传回其function object。</p>
<figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">class</span> <span class="title class_">MeanValue</span></span><br><span class="line">&#123;</span><br><span class="line"><span class="keyword">private</span>:</span><br><span class="line">    <span class="type">long</span> num;</span><br><span class="line">    <span class="type">long</span> sum;</span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line">    <span class="built_in">MeanValue</span> (): <span class="built_in">num</span>(<span class="number">0</span>), <span class="built_in">sum</span>(<span class="number">0</span>)&#123;&#125;</span><br><span class="line">    <span class="function"><span class="type">void</span> <span class="title">opeartor</span><span class="params">()</span> <span class="params">(<span class="type">int</span> elem)</span></span></span><br><span class="line"><span class="function">    </span>&#123;</span><br><span class="line">        ++num;</span><br><span class="line">        sum += elem;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="function"><span class="type">double</span> <span class="title">value</span><span class="params">()</span></span></span><br><span class="line"><span class="function">    </span>&#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="built_in">static_cast</span>&lt;<span class="type">double</span>&gt;(sum) / <span class="built_in">static_cast</span>&lt;<span class="type">double</span>&gt;(sum);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="type">int</span> <span class="title">main</span><span class="params">()</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">    vector&lt;<span class="type">int</span>&gt; coll = &#123;<span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>, <span class="number">4</span>, <span class="number">5</span>, <span class="number">6</span>, <span class="number">7</span>, <span class="number">8</span>&#125;;</span><br><span class="line">    MeanValue mv = for_each(coll.<span class="built_in">begin</span>(), coll.<span class="built_in">end</span>(), <span class="built_in">MeanValue</span>());</span><br><span class="line">    cout &lt;&lt; <span class="string">&quot;mean value:&quot;</span> &lt;&lt; mv.<span class="built_in">value</span>() &lt;&lt; endl;</span><br><span class="line">	<span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>当我们需要类型时，function object还是比较方便，例如当我们需要为associative或unordered容器声明一个hash函数或一个排序准则或相等准则。Function object通常是全局性的，这一事实有利于我们把它放入头文件或程序库，而lambda则是方便局部性的指明行为。</p>
<h2 id="1-5-Predicate（判断式）与function-object（函数对象）"><a href="#1-5-Predicate（判断式）与function-object（函数对象）" class="headerlink" title="1.5.Predicate（判断式）与function object（函数对象）"></a>1.5.Predicate（判断式）与function object（函数对象）</h2><p>所谓Predicate（判断式），就是返回布尔值的函数或function object。对STL而言，并非所有返回布尔值的函数都是合法的predicate，应满足下列条件：predicate不应因为被调用而改变自身状态；predicate的拷贝应该和其正本有着相同状态（目前的STL实现中只有remove_if()算法有此问题，换用remove_copy_if(),一切正常。<br><strong>为了使返回布尔值的函数都是合法的predicate，我们应该将operator()声明为const函数</strong>。</p>
<h1 id="2-函数适配器Binder"><a href="#2-函数适配器Binder" class="headerlink" title="2.函数适配器Binder"></a>2.函数适配器Binder</h1><p>所谓的function adapter(函数适配器），是指能将不同的function object(或是和某值或某寻常函数）结合起来的东西，它自身也是个function object。C++11开始STL预定义的函数适配器如下：</p>
<table>
<thead>
<tr>
<th>表达式</th>
<th>效果</th>
</tr>
</thead>
<tbody><tr>
<td>bind(op,args…)</td>
<td>将args绑定给op</td>
</tr>
<tr>
<td>mem_fn(op)</td>
<td>调用op,把它当作某个object(或pointer to object）的成员函数</td>
</tr>
<tr>
<td>not1(op)</td>
<td>单参反向（unary negation)</td>
</tr>
<tr>
<td>not2(op)</td>
<td>双参反向（binary negation)</td>
</tr>
</tbody></table>
<p>最重要的adapter就是bind()。它允许你：</p>
<ul>
<li>在既有的或预定义的function object之外另配接及合成(adapter and compose)新的function object。</li>
<li>调用全局函数（global function)。</li>
<li>针对object、pointer to object和smart pointer to object 调用成员函数。</li>
</ul>
<p>一般而言bind()用来将参数绑定于<strong>可调用对象（callable object)<strong>。因此，如果一个函数、成员函数、函数对象或lambda需要若干参数，你可以将参数绑定为“明白指出的”或“被传入的”实参。欲明白指出实参，你只需写出其名称，欲使用被传入的实参，则可利用预定义占位符_1,_2,……，它们被定义于命名空间</strong>std::placeholders</strong>内。</p>
<p>以下内容介绍了binder的四个应用：</p>
<h2 id="2-1-使用STL预定义函数对象时具体指定参数"><a href="#2-1-使用STL预定义函数对象时具体指定参数" class="headerlink" title="2.1.使用STL预定义函数对象时具体指定参数"></a>2.1.使用STL预定义函数对象时具体指定参数</h2><figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">include</span><span class="string">&lt;functional&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span><span class="string">&lt;iostream&gt;</span></span></span><br><span class="line"></span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> std;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="type">int</span> <span class="title">main</span><span class="params">()</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">    <span class="keyword">auto</span> plus10 = <span class="built_in">bind</span>(<span class="built_in">plus</span>&lt;<span class="type">int</span>&gt;(), placeholders::_1, <span class="number">10</span>);  <span class="comment">//std::plus&lt;int&gt;()、std::placeholders::_1</span></span><br><span class="line">    cout &lt;&lt; <span class="string">&quot;+10:&quot;</span> &lt;&lt; <span class="built_in">plus10</span>(<span class="number">7</span>) &lt;&lt; endl;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">auto</span> plus10times2 = <span class="built_in">bind</span>(<span class="built_in">multiplies</span>&lt;<span class="type">int</span>&gt;(), <span class="built_in">bind</span>(<span class="built_in">plus</span>&lt;<span class="type">int</span>&gt;(), placeholders::_1, <span class="number">10</span>), <span class="number">2</span>);</span><br><span class="line">    cout &lt;&lt; <span class="string">&quot;+10*2:&quot;</span> &lt;&lt; <span class="built_in">plus10times2</span>(<span class="number">7</span>) &lt;&lt; endl;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">auto</span> pow3 = <span class="built_in">bind</span>(<span class="built_in">multiplies</span>&lt;<span class="type">int</span>&gt;(), <span class="built_in">bind</span>(<span class="built_in">multiplies</span>&lt;<span class="type">int</span>&gt;(), placeholders::_1, placeholders::_1), placeholders::_1);</span><br><span class="line">    cout &lt;&lt; <span class="string">&quot;x*x*x:&quot;</span> &lt;&lt; <span class="built_in">pow3</span>(<span class="number">7</span>) &lt;&lt; endl;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">auto</span> inversDivide = <span class="built_in">bind</span>(<span class="built_in">divides</span>&lt;<span class="type">double</span>&gt;(), placeholders::_2,placeholders::_1);</span><br><span class="line">    cout &lt;&lt; <span class="string">&quot;invdiv:&quot;</span> &lt;&lt; <span class="built_in">inversDivide</span>(<span class="number">49</span>, <span class="number">7</span>) &lt;&lt; endl;</span><br><span class="line">    <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>这里出现了四个不同的binder,分别定义出不同的function object。例如plus10定义为 <code>auto plus10 = bind(plus&lt;int&gt;(), placeholders::_1, 10);</code>， 它所表现的function object内部调用plus&lt;&gt;(也就是operator + ),以<strong>占位符（placeholder)</strong>_1作为第一参数&#x2F;操作数，以10作为第二参数&#x2F;操作数。占位符_1表示实际传入此表达式之第一实参。<br>为了避免重复写出命名空间placeholders，可以使用对应的using指示符：<code>using namespace std::placeholders;</code>,也可以直接调用binder而不必先为它建立一个对应的function object。例如：<code>cout&lt;&lt;bind(plus&lt;int&gt;(), _1, 10)(32)&lt;&lt;endl</code>,这会输出42。<br><strong>如果你把binder或者function object传给算法，后者会把它作用于所操作的每一个元素身上</strong>。例如：<br><code>transform(coll.begin(), coll.end(), coll.begin(), bind(plus&lt;int&gt;(), placeholders::_1, 10));</code><br>实现对集合coll每个元素加10的操作，以此方式你可以定义一个binder表现排序准则，例如“找出coll集合中第一个大于42的元素”，将被传入之实参绑定为greater&lt;&gt;的第一实参，42为第二实参：<br><code>auto pos = find_if(coll.begin(), coll.end(), bind(greater&lt;int&gt;(), placeholders::_1, 42));</code><br><strong>必须永远指明预定义的function object所使用的实参类型。</strong>如果这个类型没有被正确匹配，编译器会对它实施强制类型转换，若不成功将导致编译错误。</p>
<h2 id="2-2-调用全局函数"><a href="#2-2-调用全局函数" class="headerlink" title="2.2.调用全局函数"></a>2.2.调用全局函数</h2><figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;algorithm&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;functional&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;iostream&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;locale&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;string&gt;</span></span></span><br><span class="line"></span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> std;</span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> std::placeholders;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="type">char</span> <span class="title">myToupper</span><span class="params">(<span class="type">char</span> c)</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">    std::locale loc;</span><br><span class="line">    <span class="keyword">return</span> std::use_facet&lt;std::ctype&lt;<span class="type">char</span>&gt;&gt;(loc).<span class="built_in">toupper</span>(c);</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="type">int</span> <span class="title">main</span><span class="params">()</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">    <span class="function">string <span class="title">s</span><span class="params">(<span class="string">&quot;Internationalization&quot;</span>)</span></span>;</span><br><span class="line">    <span class="function">string <span class="title">sub</span><span class="params">(<span class="string">&quot;Nation&quot;</span>)</span></span>;</span><br><span class="line"></span><br><span class="line">    string::iterator pos;</span><br><span class="line">    pos = <span class="built_in">search</span>(s.<span class="built_in">begin</span>(), s.<span class="built_in">end</span>(), sub.<span class="built_in">begin</span>(), sub.<span class="built_in">end</span>(), <span class="built_in">bind</span>(<span class="built_in">equal_to</span>&lt;<span class="type">char</span>&gt;(), <span class="built_in">bind</span>(myToupper, _1), <span class="built_in">bind</span>(myToupper, _2)));</span><br><span class="line">    <span class="keyword">if</span> (pos != s.<span class="built_in">end</span>())</span><br><span class="line">    &#123;</span><br><span class="line">        cout &lt;&lt; <span class="string">&quot;\&quot;&quot;</span> &lt;&lt; sub &lt;&lt; <span class="string">&quot;\&quot;is part of \&quot;&quot;</span> &lt;&lt; s &lt;&lt; <span class="string">&quot;\&quot;&quot;</span> &lt;&lt; endl;</span><br><span class="line">    &#125;</span><br><span class="line">	<span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>这里我们使用search()算法检验sub是否为s的一个子字符串，大小写不计。以下：<code>bind(equal_to&lt;char&gt;(), bind(myToupper, _1), bind(myToupper, _2));</code>便是建立一个function object并相当于调用<code>myToupper(param1)==myToupper(param2）</code>。<br>注意，**bind()内部会复制被传入的实参。若要改变实参，让function object使用一个reference指向被传入的实参，可利用ref()或cref()**。例如：</p>
<figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="type">void</span> <span class="title">incr</span><span class="params">(<span class="type">int</span>&amp; i)</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">	++i;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="type">int</span> i=<span class="number">0</span>;</span><br><span class="line"><span class="built_in">bind</span>(incr, i)();</span><br><span class="line"><span class="built_in">bind</span>(incr, <span class="built_in">ref</span>(i))();</span><br></pre></td></tr></table></figure>

<h2 id="2-3-调用成员函数"><a href="#2-3-调用成员函数" class="headerlink" title="2.3.调用成员函数"></a>2.3.调用成员函数</h2><figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;algorithm&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;functional&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;iostream&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;string&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;vector&gt;</span></span></span><br><span class="line"></span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> std;</span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> std::placeholders;</span><br><span class="line"></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">Person</span></span><br><span class="line">&#123;</span><br><span class="line"><span class="keyword">private</span>:</span><br><span class="line">    string name;</span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line">    <span class="built_in">Person</span>(<span class="type">const</span> string&amp; n): <span class="built_in">name</span>(n)&#123;&#125;</span><br><span class="line">    <span class="function"><span class="type">void</span> <span class="title">print</span><span class="params">()</span> <span class="type">const</span></span></span><br><span class="line"><span class="function">    </span>&#123;</span><br><span class="line">        cout &lt;&lt; name &lt;&lt; endl;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="function"><span class="type">void</span> <span class="title">print2</span><span class="params">(<span class="type">const</span> string&amp; prefix)</span> <span class="type">const</span></span></span><br><span class="line"><span class="function">    </span>&#123;</span><br><span class="line">        cout &lt;&lt; prefix &lt;&lt; name &lt;&lt; endl;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="type">int</span> <span class="title">main</span><span class="params">()</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">    vector&lt;Person&gt; coll = &#123;<span class="built_in">Person</span>(<span class="string">&quot;Tick&quot;</span>), <span class="built_in">Person</span>(<span class="string">&quot;Trick&quot;</span>), <span class="built_in">Person</span>(<span class="string">&quot;Track&quot;</span>)&#125;;</span><br><span class="line">    for_each(coll.<span class="built_in">begin</span>(), coll.<span class="built_in">end</span>(), <span class="built_in">bind</span>(&amp;Person::print, _1));</span><br><span class="line">    cout &lt;&lt; endl;</span><br><span class="line"></span><br><span class="line">    for_each(coll.<span class="built_in">begin</span>(), coll.<span class="built_in">end</span>(), <span class="built_in">bind</span>(&amp;Person::print2, _1, <span class="string">&quot;Person:&quot;</span>));</span><br><span class="line">    cout &lt;&lt; endl;</span><br><span class="line"></span><br><span class="line">    <span class="built_in">bind</span>(&amp;Person::print2, _1, <span class="string">&quot;This is:&quot;</span>)(<span class="built_in">Person</span>(<span class="string">&quot;nico&quot;</span>));</span><br><span class="line">    <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>其中的 <code>bind(&amp;Person::print, _1)</code> 定义一个function object，其内针对传入的Person调用param1.print()。也就是说，<strong>由于第一实参是个成员函数，下一个实参将定义“用以调用成员函数”的对象，其他任何实参都会被传递给该成员函数</strong>。这意味着：<code>bind(&amp;Person::print2, _1, &quot;Person:&quot;)</code>定义出一个function object，其内针对传入的Person调用<code>param1.print2(&quot;Person:&quot;)</code>。这里传入的对象是coll的成员（元素），原则上可以直接传递对象，例如：</p>
<figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">Person</span>(<span class="string">&quot;nico&quot;</span>);</span><br><span class="line"><span class="built_in">bind</span>(&amp;Person::print2, _1, <span class="string">&quot;This is&quot;</span>)(n);</span><br></pre></td></tr></table></figure>
<p>也就相当于调用<code>n.print2(&quot;This is:&quot;)</code>。</p>
<p>此外，<strong>你也可以调用“具有改动能力的成员函数”和virtual成员函数</strong>。如果base class的某个成员函数被绑定，而调用它的是个derived class对象，正确的derived class virtual函数会被调用。</p>
<h2 id="2-4-绑定至数据成员"><a href="#2-4-绑定至数据成员" class="headerlink" title="2.4.绑定至数据成员"></a>2.4.绑定至数据成员</h2><figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">map&lt;string, <span class="type">int</span>&gt; coll;</span><br><span class="line"></span><br><span class="line"><span class="type">int</span> sum = <span class="built_in">accumulate</span>(coll.<span class="built_in">begin</span>(), coll.<span class="built_in">end</span>(), <span class="number">0</span>, <span class="built_in">Bind</span>(<span class="built_in">plus</span>&lt;<span class="type">int</span>&gt;(), _1, <span class="built_in">bind</span>(&amp;map&lt;string, <span class="type">int</span>&gt;::value_type::second, _2)));</span><br></pre></td></tr></table></figure>

<p>这里调用accumulate()，它使用一个 binary predicate 对所有元素求和。然而由于我们的容器是个map,其元素是 key&#x2F;value pair, 为了得到对元素的value的访问权，必须这么做：<br><code>bind(&amp;map&lt;string, int&gt;::value_type::second, _2)</code><br>把“每次调用这个predicate所传入的第二实参”绑定为元素的数据成员second。</p>
<hr>

        
            <div class="donate-container">
    <div class="donate-button">
        <button id="donate-button">赞赏</button>
    </div>
    <div class="donate-img-container hide" id="donate-img-container">
        <img id="donate-img" src="" data-src="/myblog/img/donate.jpg">
        <p> 感谢鼓励 </p>
    </div>
</div>
        
        <br />
        <div id="comment-container">
        </div>
        <div id="disqus_thread"></div>
        <div id="lv-container"></div>
        <div class="giscus"></div>
    </div>
</div>

    </div>
</div>


<footer class="footer">
    <ul class="list-inline text-center">
        
        

        

        

        
        <li>
            <a target="_blank"  href="https://github.com/samuel-24276">
                            <span class="fa-stack fa-lg">
                                <i class="iconfont icon-github"></i>
                            </span>
            </a>
        </li>
        

        

    </ul>
    
    <p>
        <span>/</span>
        
        <span><a target="_blank" rel="noopener" href="https://github.com/samuel-24276">samuel-24276&#39;s Page</a></span>
        <span>/</span>
        
        <span><a target="_blank" rel="noopener" href="https://beian.miit.gov.cn/">北京-未备案</a></span>
        <span>/</span>
        
        <span><a href="#">返回顶部</a></span>
        <span>/</span>
        
    </p>
    
    <p>
        <span id="busuanzi_container_site_pv">
            <span id="busuanzi_value_site_pv"></span>PV
        </span>
        <span id="busuanzi_container_site_uv">
            <span id="busuanzi_value_site_uv"></span>UV
        </span>
        Created By <a target="_blank" rel="noopener" href="https://hexo.io/">Hexo</a>  Theme <a target="_blank" rel="noopener" href="https://github.com/aircloud/hexo-theme-aircloud">AirCloud</a></p>
</footer>




</body>

<script>
    // We expose some of the variables needed by the front end
    window.hexo_search_path = "search.json"
    window.hexo_root = "/myblog/"
    window.isPost = true
</script>
<script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.min.js"></script>

<script src="/myblog/js/index.js"></script>

<script async src="//busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js"></script>






    <script type="text/javascript">
       (function() {
           if (typeof LivereTower === 'function') { return; }

           var j, d = document.getElementById('lv-container');

           d.setAttribute('data-id','city');
           d.setAttribute('data-uid' , 'MTAyMC80OTA5OC8yNTU5Mw==');

           j = document.createElement('script');
           j.src = 'https://cdn-city.livere.com/js/embed.dist.js';
           j.async = true;

           d.appendChild(j);
       })();
    </script>
    <noscript>为正常使用来必力评论功能请激活JavaScript</noscript>
    </div>

</html>
